package ee.ttu.agent.smartHouse.agent;

import jade.core.AID;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.gui.GuiAgent;
import jade.gui.GuiEvent;

import java.util.HashMap;
import java.util.Map;

import ee.ttu.agent.smartHouse.gui.FacilitatorAgentGui;
import ee.ttu.agent.smartHouse.gui.OnlineInteractionGui;
import ee.ttu.agent.smartHouse.services.FacilitatorAuthorizationCheckRequestBehaviour;
import ee.ttu.agent.smartHouse.services.DorOpenerBehavior;
import ee.ttu.agent.smartHouse.services.OnlineInteractionBehaviour;
import ee.ttu.agent.smartHouse.util.Constants;
import ee.ttu.agent.smartHouse.util.CustomACLMessage;
import ee.ttu.agent.smartHouse.util.CustomEventTypes;
import ee.ttu.agent.smartHouse.util.IOnlineInteractor;

public class FacilitatorAgent extends GuiAgent implements IOnlineInteractor {
	private static final long serialVersionUID = -8135023251022142928L;
	transient protected FacilitatorAgentGui myGui;

	private OnlineInteractionGui myOnlineInteraction;
	private boolean oiOn = false;

	private void getOnlineInteractionGui() {
		if (!oiOn) {
			myOnlineInteraction = new OnlineInteractionGui(this);
			oiOn = true;
		}
	}

	transient private final Map<String, Boolean> registeredUsers = new HashMap<>();
	private DorOpenerBehavior dorOpener;
	
	
	public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";

	// private AID[] loggingServices;

	protected void setup() {
		DFAgentDescription dfd = new DFAgentDescription();
		ServiceDescription sd = new ServiceDescription();
		sd.setType(Constants.AUTHORIZATION_CHECK_SERVICE);
		sd.setName(getName());
		sd.setOwnership(Constants.APP_NAME);
		dfd.addServices(sd);
		dfd.setName(getAID());
		try {
			DFService.register(this, dfd);
		} catch (FIPAException e) {
			System.err.println(getLocalName()
					+ " registration with DF unsucceeded. Reason: "
					+ e.getMessage());
			doDelete();
		}
		
		dorOpener = new DorOpenerBehavior(this);
		registeredUsers.put("user1", true);
		registeredUsers.put("user3", true);
		myGui = new FacilitatorAgentGui(this);
		myGui.setVisible(true);

		addBehaviour(new FacilitatorAuthorizationCheckRequestBehaviour(this));
	}

	// Put agent clean-up operations here
	protected void takeDown() {
		// Printout a dismissal message
		System.out.println("User Agent Terminated.");
	}

	public void openDor(boolean remeber) {
		myGui.openDor();
		if(remeber){
			String authCode = myGui.getAuthCode();
			registeredUsers.put(authCode, true);
		}
	}
	
	public void onHoldDor() {
		myGui.onHoldDor();
	}

	public void closeDor() {
		myGui.closeDor();
	}

	public String getAuthCode() {
		return myGui.getAuthCode();
	}
	
	@Override
	protected void onGuiEvent(GuiEvent arg0) {
		// todo: create or investigate proper statuses for dispatching of events

		if (arg0.getType() == CustomEventTypes.KILL_AGENT) {
			// remove agent from container:
			doDelete();
		}

		if (arg0.getType() == CustomEventTypes.ENTRANCE_ATTEMPT) {
			dorOpener.reset();
			addBehaviour(dorOpener);
		}

		if (arg0.getType() == CustomEventTypes.OI_OUTBOUND) {

			String messageContent = arg0.getParameter(0).toString();
			CustomACLMessage cACL = new CustomACLMessage();
			cACL.setPerformative(CustomACLMessage.FROM_USER);
			cACL.setContent(this.getParentId() + ": " + messageContent);
			cACL.setOntology(Constants.OI_MESSAGES);
			
			cACL.addReceiver(new AID("Supervisor", AID.ISLOCALNAME));
			cACL.setSender(this.getAID());
			send(cACL);
		}
	}

	@Override
	public void setMessage(String outgouingMessage) {
		myOnlineInteraction.setTypedText(outgouingMessage);
	}

	@Override
	public String getMessage() {
		return null;
	}

	@Override
	public String getParentId() {
		return this.getLocalName();
	}

	@Override
	public void disposeOnlineInteractor() {
		this.myOnlineInteraction = null;
		this.oiOn = false;
	}

	public Map<String, Boolean> getRegisteredUsers() {
		return registeredUsers;
	}

	@Override
	public void acceptOIRequest() {
		// TODO Auto-generated method stub
		getOnlineInteractionGui();
	}
}
